import pygame as pg
import time

CHESSBOARD_SIZE = 16
SQUARE_SIZE = 32    # 一个格子的像素大小
WINDOWS_SIZE = SQUARE_SIZE * CHESSBOARD_SIZE


pg.init()
screen = pg.display.set_mode((WINDOWS_SIZE, WINDOWS_SIZE))
screen.fill((200, 225, 225))
pg.display.set_caption("五子棋")
font = pg.font.Font(None, 24)


moves_stack = []
step_number = 0
def draw_rect():
    for row in range(16):
        for col in range(16):
            x = col * SQUARE_SIZE
            y = row * SQUARE_SIZE
            pg.draw.rect(screen, (0, 0, 0), (x, y, SQUARE_SIZE, SQUARE_SIZE), 1)  # 画空心矩形
    pg.display.flip()

class chess_piece:
    __all__color_chess_list = []  # 私有属性
    def __init__(self, chess_color):
        self.chess_color = chess_color
        self.__chess_list = []

    def __check_chess_exist(self, pos: tuple) -> bool:
        if pos not in self.__all__color_chess_list:
            self.__all__color_chess_list.append(pos)
            self.__chess_list.append(pos)
            return False
        else:
            return True
    
    @property
    def chess_list(self):
        return self.__chess_list
    
    def remove_chess(self, pos: tuple):
        """ 移除棋子 """
        if pos in self.__all__color_chess_list:
            self.__all__color_chess_list.remove(pos)
            self.__chess_list.remove(pos)

    def draw_chess(self, position):
        x, y = position
        row = x // SQUARE_SIZE  # 行
        col = y // SQUARE_SIZE  # 列
        
        if not self.__check_chess_exist((row, col)):   
            center_x = row * SQUARE_SIZE + SQUARE_SIZE // 2
            center_y = col * SQUARE_SIZE + SQUARE_SIZE // 2
            radius = SQUARE_SIZE // 2 - 5  # 圆形半径
            
            if self.chess_color == "Black":
                pg.draw.circle(screen, (0, 0, 0), (center_x, center_y), radius)
                pg.display.flip()
            if self.chess_color == "White":
                pg.draw.circle(screen, (255, 255, 255), (center_x, center_y), radius)
                pg.display.flip()
            
            # 绘制步数
            text = font.render(str(step_number), True, (255, 255, 255) if self.chess_color == "Black" else (0, 0, 0))
            text_rect = text.get_rect(center=(center_x, center_y))
            screen.blit(text, text_rect)
            pg.display.flip()
            
            # 记录操作
            moves_stack.append(((row, col), self.chess_color))
            
            return 1
        else:
            print("We're already played chess pieces here...")
            return 0

def lineation(points: list, line_number: int = 5) -> list[bool, list[tuple]]:
    if len(points) < line_number:
        return False, []
    
    directions = [
        (0, 1),  # 横向
        (1, 0),  # 竖向
        (1, 1),  # 正对角线
        (1, -1)  # 反对角线
    ]
    for x, y in points:
        for dx, dy in directions:
            count = 1
            winning_positions = [(x, y)]    # 有序列表
            for i in range(1, 5):
                nx, ny = x + i * dx, y + i * dy
                if (nx, ny) in points:
                    count += 1
                    winning_positions.append((nx, ny))
                else:
                    break
            for i in range(1, 5):
                nx, ny = x - i * dx, y - i * dy
                if (nx, ny) in points:
                    count += 1
                    winning_positions.insert(0, (nx, ny))
                else:
                    break

            if count >= line_number:
                return True, winning_positions
    return False, []
def draw_victory_line(positions):
    """
    Draw a red line connecting the centers of the given positions.
    """
    points = [(
        pos[0] * SQUARE_SIZE + SQUARE_SIZE // 2,    # row, X
        pos[1] * SQUARE_SIZE + SQUARE_SIZE // 2
    ) for pos in positions]
    
    pg.draw.lines(screen, (255, 0, 0), False, points, 5)
    pg.display.flip()
def main():
    draw_rect()
    balck = chess_piece("Black")
    white = chess_piece("White")
    while True:
        global step_number
        step_number= len(balck.chess_list) + len(white.chess_list)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
                exit()
            elif event.type == pg.MOUSEBUTTONDOWN:
                if event.button == 1:
                    print(f"pos:{event.pos},row:{event.pos[0] // SQUARE_SIZE},col:{event.pos[1] // SQUARE_SIZE}")
                    if step_number % 2 == 0:
                        try_draw = balck.draw_chess(event.pos)
                        if lineation(balck.chess_list)[0]:
                            print("The Black player is winner!!!")
                            draw_victory_line(lineation(balck.chess_list)[1])
                            time.sleep(15)
                            pg.quit()
                            exit()
                        if try_draw:
                            print("Now is White...")
                        else:
                            print("Now is Balck...")
                    else:
                        try_draw = white.draw_chess(event.pos)
                        if lineation(white.chess_list)[0]:
                            print("The White player is winner!!!")
                            draw_victory_line(lineation(white.chess_list)[1])
                            time.sleep(15)
                            pg.quit()
                            exit()
                        if try_draw:
                            print("Now is Balck...")
                        else:
                            print("Now is White...")

                elif event.button == 3:  # 鼠标右键点击
                    if moves_stack:
                        (row, col), color = moves_stack.pop()
                        if color == "Black":
                            balck.remove_chess((row, col))
                        else:
                            white.remove_chess((row, col))
                        
                        # 清除棋子
                        x = row * SQUARE_SIZE
                        y = col * SQUARE_SIZE
                        pg.draw.rect(screen, (200, 225, 225), (x, y, SQUARE_SIZE, SQUARE_SIZE))
                        draw_rect()
                        pg.display.flip()
                        print("撤销成功...")
                    else:
                        print("已经清空了...")

        pg.display.flip()
        
if __name__ == '__main__':
    main() 


